/************************************************************************/
/*    Author: Scott Bevin     
/************************************************************************/

#include "GameEntity.h"
#include "../XEntityComponents/EntityComponentFactory.h"
#include "../XEntityComponents/EntityComponent.h"

namespace XF
{
	GameEntity::GameEntity() : mInitialized(false),mDead(false)
	{	
		mShutdown = false;
	}

	GameEntity::GameEntity(GameEntity &copy) : ComponentContainer(copy), PropertyContainer(copy)
 	{
		mDead = false;
		mShutdown = false;
	}

	GameEntity::~GameEntity()
	{

	}

	void GameEntity::Update( double dT )
	{
		UpdateComponents(dT);
	}

	void GameEntity::HandleInput(double dT, XF::Input* input)
	{
		HandleInputComponents(dT, input);
	}

	bool GameEntity::OnHandleMessage( const XF::Message& message )
	{
		return MessageComponents(message);
	}
 
	void GameEntity::Initialize()
	{
		mInitialized = true;

		InitializeComponents();

		PostAMessage(ID(), MessageSubject::CREATED);
	}

	void GameEntity::ClearComponents()
	{
		for(int i = 0; i < (int)mComponents.size(); ++i)
		{
			EntityComponent* thisComp = mComponents[i];

			thisComp->Shutdown();// chris
			thisComp->Kill();
		}
	}

	void GameEntity::IntegrateEntity( GameEntity *ent )
	{
		for(int i = 0; i < (int)ent->mComponents.size(); ++i)
		{
			EntityComponent* thisComp = ent->mComponents[i];

			EntityComponent* newComp = EntityComponentFactory::CreateComponent(thisComp->ComponentName(), this);

			newComp->CopyPropertys(thisComp);

			AddComponent(newComp);
		}

		for(std::map<std::string, IProperty*>::const_iterator it = ent->mProperties.begin();
			it != ent->mProperties.end(); ++it)
		{
			IProperty* newProp = PropertyFactory::CreateProperty(it->second->TypeID(), it->first, it->second->ToString());
			AddProperty(newProp);
		}
	}

	void GameEntity::CopyEntity( GameEntity *ent )
	{
		ClearEntity();
		//Update( 0 ) ;//chris added so that components marked for death are deleted
		IntegrateEntity(ent);
	}

	void GameEntity::Shutdown()
	{
		if(!mShutdown && mInitialized)
		{
			mShutdown = true;
			ClearEntity();
			Update(0); //chris, delete all components marked for killing 
		}
		
	}
}